﻿using Microsoft.CodeAnalysis.CSharp.Syntax;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UMLSynthesizer.CSharpAnalyzer.Helpers;
using UMLSynthesizer.LangAnalyzer;
using UMLSynthesizer.LangAnalyzer.Elements;
using UMLSynthesizer.LangAnalyzer.ExtensionMethods;

namespace UMLSynthesizer.CSharpAnalyzer.Elements
{
    class CSharpPropertyElement : IPropertyElement
    {
        #region Fields

        PropertyDeclarationSyntax elementNode;
        CSharpElementWithAccessorsHelper accessorsHelper;
        CSharpElementWithAttributesHelper attributesHelper;

        #endregion

        #region Constructor

        public CSharpPropertyElement(PropertyDeclarationSyntax elementNode, IElementBase parentElement)
        {
            if (elementNode == null)
                throw new ArgumentNullException("elementNode");
            if (parentElement == null)
                throw new ArgumentNullException("parentElement");

            this.elementNode = elementNode;
            this.ParentElement = parentElement;
            this.ProjectOwner = parentElement.ProjectOwner;
            this.accessorsHelper = new CSharpElementWithAccessorsHelper(this, elementNode);
            this.attributesHelper = new CSharpElementWithAttributesHelper(elementNode);

            this.MetricDictionary = new Dictionary<LanguageAnalyzer.Metrics, double>();
        }

        #endregion

        #region Properties

        public string Identifier { get { return elementNode.Identifier.ToString(); } }
        public ElementKinds Kind { get { return ElementKinds.Property; } }
        public IElementBase ParentElement { get; private set; }
        public IProjectElement ProjectOwner { get; private set; }

        public ITypeBase Type { get { return (ProjectOwner as CSharpProjectElement).GetTypeReference(elementNode.Type); } }

        public bool IsAbstract { get { return attributesHelper.IsAbstract; } }
        public bool IsStatic { get { return attributesHelper.IsStatic; } }
        public VisibilityStates Visibility { get { return attributesHelper.Visibility; } }

        public IEnumerable<IAccessorElement> Accessors { get { return accessorsHelper.Accessors; } }
        public IAccessorElement GetAccessor
        {
            get 
            {
                return (from accessor in Accessors
                        where accessor.Identifier == "get"
                        select accessor).FirstOrDefault();
            } 
        }
        public IAccessorElement SetAccessor
        {
            get
            {
                return (from accessor in Accessors
                        where accessor.Identifier == "set"
                        select accessor).FirstOrDefault();
            }
        }

        public Dictionary<LanguageAnalyzer.Metrics, double> MetricDictionary { get; private set; }

        #endregion
    }
}
